// scanners/FileScanner.js
const fs = require('fs').promises;
const fsSync = require('fs');
const path = require('path');
const crypto = require('crypto');
const {getFileType} = require("../util/file");

class FileScanner {
    constructor(cacheManager) {
        this.cacheManager = cacheManager;
        this.scanStats = {
            totalFiles: 0,
            totalDirs: 0,
            scanTime: 0,
            vaults: new Map()
        };
    }

    async scanVault(vaultConfig) {
        const startTime = Date.now();
        const cacheKey = this.cacheManager.generateCacheKey(vaultConfig.path, vaultConfig.patterns);

        console.log(`🔍 Scanning vault: ${vaultConfig.name} at ${vaultConfig.path}`);

        // 检查缓存有效性
        if (vaultConfig.cacheEnabled && await this.cacheManager.isCacheValid(cacheKey, vaultConfig.path)) {
            const cachedResult = await this.cacheManager.getCache(cacheKey);
            if (cachedResult) {
                console.log(`✅ Using cached results for ${vaultConfig.name} (${cachedResult.files.length} files)`);
                this.updateScanStats(vaultConfig.name, cachedResult.files.length, 0, Date.now() - startTime);
                return cachedResult.files;
            }
        }

        try {
            // 验证目录存在性
            await this.validateDirectory(vaultConfig.path);

            // 执行扫描
            const files = await this.recursiveScan(vaultConfig.path, vaultConfig.patterns, vaultConfig);
            const organizedFiles = this.organizeFiles(files, vaultConfig);

            // 更新扫描统计
            this.updateScanStats(vaultConfig.name, organizedFiles.length, 0, Date.now() - startTime);

            // 更新缓存
            if (vaultConfig.cacheEnabled) {
                const cacheData = {
                    files: organizedFiles,
                    scanTime: new Date().toISOString(),
                    fileCount: organizedFiles.length
                };
                await this.cacheManager.setCache(cacheKey, cacheData);
            }

            console.log(`✅ Scanned ${vaultConfig.name}: ${organizedFiles.length} files found`);
            return organizedFiles;

        } catch (error) {
            console.error(`❌ Failed to scan vault ${vaultConfig.name}:`, error.message);
            throw error;
        }
    }

    async validateDirectory(dirPath) {
        try {
            const stats = await fs.stat(dirPath);
            if (!stats.isDirectory()) {
                throw new Error(`Path is not a directory: ${dirPath}`);
            }

            // 检查读取权限
            await fs.access(dirPath, fs.constants.R_OK);
            return true;

        } catch (error) {
            if (error.code === 'ENOENT') {
                throw new Error(`Directory does not exist: ${dirPath}`);
            }
            throw error;
        }
    }

    async recursiveScan(dirPath, patterns, vaultConfig, depth = 0) {
        // 防止无限递归和深度过大
        if (depth > 100) {
            console.warn(`⚠️  Maximum depth reached at: ${dirPath}`);
            return [];
        }

        const results = [];

        try {
            const items = await fs.readdir(dirPath, { withFileTypes: true });

            for (const item of items) {
                const fullPath = path.join(dirPath, item.name);

                // 跳过隐藏文件和系统文件
                if (this.shouldSkipFile(item.name, vaultConfig.skipPatterns)) {
                    continue;
                }

                if (item.isDirectory()) {
                    // // 递归扫描子目录
                    // const subResults = await this.recursiveScan(fullPath, patterns, vaultConfig, depth + 1);
                    // results.push(...subResults);
                    // 检查是否为剧集目录（包含__hash模式）
                    if (this.isSeriesDirectory(item.name, vaultConfig)) {
                        results.push({
                            path: fullPath,
                            name: item.name,
                            relativePath: path.relative(vaultConfig.path, fullPath),
                            type: 'series',
                            isDirectory: true
                        });
                    } else {
                        // 递归扫描子目录
                        const subResults = await this.recursiveScan(fullPath, patterns, vaultConfig, depth + 1);
                        results.push(...subResults);
                    }

                } else if (item.isFile()) {
                    // 检查文件是否符合模式
                    if (this.matchesPattern(fullPath, patterns, vaultConfig)) {
                        results.push({
                            path: fullPath,
                            name: item.name,
                            relativePath: path.relative(vaultConfig.path, fullPath),
                            type: getFileType(item.name),
                            isDirectory: false,
                            size: await this.getFileSize(fullPath),
                            mtime: await this.getFileMtime(fullPath)
                        });
                    }
                }
            }

        } catch (error) {
            console.error(`Error scanning directory ${dirPath}:`, error.message);
            // 不抛出错误，继续扫描其他目录
        }

        return results;
    }

    shouldSkipFile(filename, skipPatterns) {
        // 跳过隐藏文件、系统文件等
        let skipPatternsTotal = [
            /^\./, // 隐藏文件
            /^~/, // 临时文件
            /^Thumbs\.db$/i, // Windows缩略图
            /^\.DS_Store$/i, // macOS系统文件
            /^desktop\.ini$/i, // Windows系统文件
        ];
        if (skipPatterns) {
            skipPatternsTotal = skipPatternsTotal.concat(skipPatterns);
        }

        return skipPatternsTotal.some(pattern => pattern.test(filename));
    }

    matchesPattern(filePath, patterns, vaultConfig) {
        const filename = path.basename(filePath);

        // 基本模式匹配
        for (const pattern of patterns) {
            if (pattern.test(filename) || pattern.test(filePath)) {
                return true;
            }
        }

        // // 特殊处理：vault2的hash模式
        // if (vaultConfig.name === 'vault2' || pattern.toString().includes('__')) {
        //     return this.matchesHashPattern(filePath);
        // }

        return false;
    }

    // matchesHashPattern(filePath) {
    //     // 匹配包含__{hash}的模式，例如：filename__8523c933e1fc7f53057dffe176bee6b79f50c405.html
    //     const hashPattern = /__[a-f0-9]{8,}/i;
    //     return hashPattern.test(filePath);
    // }

    isSeriesDirectory(dirName, vaultConfig) {
        const result = vaultConfig.patterns.filter(regex => regex.toString().includes(".folder")).length > 0;
        // 检查目录名是否包含hash模式（剧集目录特征）
        const seriesPattern = /__[a-f0-9]{8,}/i;
        return seriesPattern.test(dirName) && result;
    }

    // getFileType(filename) {
    //     const ext = path.extname(filename).toLowerCase();
    //     const typeMap = {
    //         // 文档类型
    //         '.md': 'markdown',
    //         '.txt': 'text',
    //         '.pdf': 'pdf',
    //         '.doc': 'word',
    //         '.docx': 'word',
    //
    //         // 代码文件
    //         '.js': 'javascript',
    //         '.ts': 'typescript',
    //         '.py': 'python',
    //         '.java': 'java',
    //         '.html': 'html',
    //         '.css': 'css',
    //         '.json': 'json',
    //
    //         // 图片类型
    //         '.jpg': 'image',
    //         '.jpeg': 'image',
    //         '.png': 'image',
    //         '.gif': 'image',
    //         '.bmp': 'image',
    //         '.svg': 'image',
    //
    //         // 视频类型
    //         '.mp4': 'video',
    //         '.avi': 'video',
    //         '.mkv': 'video',
    //         '.mov': 'video',
    //         '.wmv': 'video',
    //         '.flv': 'video',
    //
    //         // 音频类型
    //         '.mp3': 'audio',
    //         '.wav': 'audio',
    //         '.flac': 'audio',
    //         '.aac': 'audio'
    //     };
    //
    //     return typeMap[ext] || 'file';
    // }

    async getFileSize(filePath) {
        try {
            const stats = await fs.stat(filePath);
            return stats.size;
        } catch {
            return 0;
        }
    }

    async getFileMtime(filePath) {
        try {
            const stats = await fs.stat(filePath);
            return stats.mtime;
        } catch {
            return new Date();
        }
    }

    organizeFiles(files, vaultConfig) {
        return files.map(file => {
            // 为文件添加额外的元数据
            return {
                ...file,
                vault: vaultConfig.name,
                handler: this.determineHandler(file, vaultConfig),
                // route: this.generatePreviewRoute(file, vaultConfig)
            };
        });
    }

    determineHandler(file, vaultConfig) {
        // 如果是目录，使用series handler
        if (file.isDirectory) {
            return 'series';
        }

        // 根据vault配置和文件类型确定处理器
        const handlerMap = {
            'vault1': {
                'markdown': 'markdown',
                'default': 'markdown'
            },
            'vault2': {
                'html': 'html',
                'video': 'video',
                'default': 'html'
            },
            'vault3': {
                'video': 'video',
                'default': 'video'
            }
        };

        const vaultHandlers = handlerMap[vaultConfig.name] || handlerMap['vault2'];
        return vaultHandlers[file.type] || vaultHandlers['default'];
    }

    // generatePreviewRoute(file, vaultConfig) {
    //     let route = file.relativePath.replace(/\\/g, '/');
    //
    //     // 移除扩展名
    //     if (!file.isDirectory) {
    //         route = route.replace(/\.[^/.]+$/, '');
    //     }
    //
    //     // 处理特殊模式（如hash清理）
    //     if (vaultConfig.pattern.toString().includes('__')) {
    //         route = route.replace(/__[a-f0-9]+/g, '');
    //     }
    //
    //     // 清理路径
    //     route = route.replace(/\/+/g, '/').replace(/^\/|\/$/g, '');
    //
    //     return `/${vaultConfig.name}/${route}`.replace(/\/+/g, '/');
    // }

    updateScanStats(vaultName, fileCount, dirCount, scanTime) {
        this.scanStats.vaults.set(vaultName, {
            fileCount,
            dirCount,
            scanTime,
            lastScanned: new Date().toISOString()
        });

        this.scanStats.totalFiles += fileCount;
        this.scanStats.totalDirs += dirCount;
        this.scanStats.scanTime += scanTime;
    }

    getScanStats() {
        return {
            ...this.scanStats,
            vaults: Object.fromEntries(this.scanStats.vaults)
        };
    }

    // 批量扫描多个vault
    async scanMultipleVaults(vaultConfigs) {
        const results = {};
        const scanPromises = [];

        for (const vaultConfig of vaultConfigs) {
            const promise = this.scanVault(vaultConfig)
                .then(files => {
                    results[vaultConfig.name] = files;
                    return files;
                })
                .catch(error => {
                    console.error(`Failed to scan vault ${vaultConfig.name}:`, error);
                    results[vaultConfig.name] = [];
                    return [];
                });

            scanPromises.push(promise);
        }

        await Promise.all(scanPromises);
        return results;
    }

    // 清理缓存
    async clearCache(vaultPath = null) {
        if (vaultPath) {
            const cacheKey = this.cacheManager.generateCacheKey(vaultPath, '.*');
            return await this.cacheManager.clearCache(cacheKey);
        } else {
            return await this.cacheManager.clearAllCache();
        }
    }
}

module.exports = FileScanner;